#region AppServices License

// Product: 
// AppServices
// http://appservices.codeplex.com
//
// Author:
// Pawel Idzikowski
// http://www.polenter.com
// mailto:idzikowski@polenter.com?subject=AppServices-Question
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the author(s) be held liable for any damages arising from
// the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
//    1. The origin of this software must not be misrepresented; you must not
//      claim that you wrote the original software. If you use this software
//      in a product, an acknowledgment in the product documentation would be
//      appreciated but is not required.
//
//    2. Altered source versions must be plainly marked as such, and must not
//      be misrepresented as being the original software.
//
//    3. This notice may not be removed or altered from any source distribution.

#endregion

using System.Reflection;

namespace Polenter.Services.Internal
{
    /// <summary>
    /// Searches for a service in the services and injects it to a field or property of the target object
    /// </summary>
    internal class ServiceInjector
    {
        private readonly bool _injectOnlyNullMembers;
        private readonly AppServices _services;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        /// <param name="injectOnlyNullMembers">if true, only these members are injected which are null. 
        /// Checking if a member is null lowers the performance.</param>
        public ServiceInjector(AppServices services, bool injectOnlyNullMembers)
        {
            _services = services;
            _injectOnlyNullMembers = injectOnlyNullMembers;
        }

        public void InjectService(FieldInfo info, object target)
        {
            if (_injectOnlyNullMembers && info.GetValue(target) != null) return;

            object service = _services.GetService(info.FieldType);
            info.SetValue(target, service);
        }

        public void InjectService(PropertyInfo info, object target)
        {
            if (_injectOnlyNullMembers && info.GetValue(target, null) != null) return;

            object service = _services.GetService(info.PropertyType);
            info.SetValue(target, service, null);
        }
    }
}